﻿using eLoan.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace eLoan.Controllers
{
    public class LoanController : BaseController
    {
        public ActionResult AddEdit(string documentNo, string branchCode)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();

                var loanAddEditModel = FundingHelper.GetLoanAddEditModel(db, documentNo, branchCode, User.Identity.Name);

                return View("AddEdit", loanAddEditModel);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        [HttpPost]
        public ActionResult Save(LoanAddEditModel loanAddEditModel, string command)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                if (ModelState.IsValid)
                {
                    using (var db = new DatabaseContext())
                    {
                        if (command == AdministrationHelper.DBCommand.Add.ToString())
                        {
                            db.Loans.Add(loanAddEditModel.LoanModel.Loan);
                            db.SaveChanges();
                            CopyLoanCoMakersAndCollaterals(db, loanAddEditModel.LoanModel.Loan);
                            return RedirectToAction("LoanDetails", "Loan", new { documentNo = loanAddEditModel.LoanModel.Loan.DocumentNo });
                        }
                        else if (command == AdministrationHelper.DBCommand.Edit.ToString())
                        {
                            db.Entry(loanAddEditModel.LoanModel.Loan).State = System.Data.EntityState.Modified;
                            db.SaveChanges();
                            CopyLoanCoMakersAndCollaterals(db, loanAddEditModel.LoanModel.Loan);
                            return RedirectToAction("LoanDetails", "Loan", new { documentNo = loanAddEditModel.LoanModel.Loan.DocumentNo });
                        }
                        else
                        {
                            // cancelled
                            return RedirectToAction("Loans", "Funding");
                        }
                    }
                }

                return RedirectToAction("Loans", "Funding");
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        private void CopyLoanCoMakersAndCollaterals(DatabaseContext db, Loan loan)
        {
            var loanCollaterals = new List<LoanCollateral>();
            var loanCoMakers = new List<LoanCoMaker>();

            var collaterals = db.BorrowerCollaterals.Where(w => w.BorrowerID == loan.BorrowerID);
            var comakers = db.BorrowerCoMakers.Where(w => w.BorrowerID == loan.BorrowerID);

            var oldCollaterals = db.LoanCollaterals.Where(w => w.DocumentNo == loan.DocumentNo);
            foreach(var col in oldCollaterals)
            {
                db.LoanCollaterals.Remove(col);
            }

            var oldComakers = db.LoanCoMakers.Where(w => w.DocumentNo == loan.DocumentNo);
            foreach (var com in oldComakers)
            {
                db.LoanCoMakers.Remove(com);
            }

            foreach (var collateral in collaterals)
            {
                var loanCollateral = new LoanCollateral();
                loanCollateral.Amount = collateral.Amount;
                loanCollateral.MakeOrType = collateral.MakeOrType;
                loanCollateral.BrandOrFileNo = collateral.BrandOrFileNo;
                loanCollateral.SerialOrPlateNo = collateral.SerialOrPlateNo;
                loanCollateral.DocumentNo = loan.DocumentNo;

                db.LoanCollaterals.Add(loanCollateral);
            }

            foreach (var comaker in comakers)
            {
                var loanCoMaker = new LoanCoMaker();
                loanCoMaker.Address = comaker.Address;
                loanCoMaker.CoMakerName = comaker.CoMakerName;
                loanCoMaker.ContactNumbers = comaker.ContactNumbers;
                loanCoMaker.DocumentNo = loan.DocumentNo;
                loanCoMaker.IDNo = comaker.IDNo;

                db.LoanCoMakers.Add(loanCoMaker);
            }

            db.SaveChanges();
        }

        public ActionResult LoanDetails(string documentNo)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var loanDetails = FundingHelper.GetLoanDetailsModel(new DatabaseContext(), documentNo, User.Identity.Name);

                return View(loanDetails);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult LoanCoMakersAndCollaterals(string documentNo, int? borrowerID, string branchCode)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();
                var model = new LoanCoMakerCollateralModel();

                model.DocumentNo = documentNo;
                model.BranchCode = branchCode;
                model.BorrowerName = AdministrationHelper.GetBorrowerName(borrowerID.GetValueOrDefault());
                model.LoanCoMakers = db.LoanCoMakers.Where(w => w.DocumentNo == documentNo).ToList();
                model.LoanCollaterals = db.LoanCollaterals.Where(w => w.DocumentNo == documentNo).ToList();

                return View(model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult SearchBorrowers(string branchCode, string searchText, bool excludeWithActiveLoans = true)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var borrowerItems = MasterFilesHelper.GetBorrwerList(branchCode, searchText, excludeInactive: true, excludeWithActiveLoans: excludeWithActiveLoans);
                return Json(borrowerItems, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult SaveDetails(string documentNo, int paymentTypeID)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();

                var loan = db.Loans.Where(w => w.DocumentNo == documentNo).SingleOrDefault();
                loan.PaymentTypeID = paymentTypeID;
                db.Entry(loan).State = System.Data.EntityState.Modified;
                db.SaveChanges();


                return Json("", JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult GetAgents(string branchCode)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();

                var agents = db.Agents.Where(w => w.BranchCode == branchCode);
                var agentList = AdministrationHelper.GetAgentDropDownList(agents);

                return Json(agentList, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult GetNextLoanDocumentNo(string branchCode)
        {
            try
            {
                var db = new DatabaseContext();
                var documentNo = FundingHelper.GetNextLoanDocumentNo(db, branchCode);

                return Json(documentNo, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult LoanJournal(string documentNo)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();
                var model = FundingHelper.GetLoanJournalModel(db, documentNo);
                return View(model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        [HttpPost]
        public ActionResult SaveLoanJournalRemarks(LoanJournalModel model)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();

                var journal = new LoanJournal();
                journal.DocumentNo = model.DocumentNo;
                journal.Remarks = model.Remarks;
                journal.JournalDate = DateTime.Today;
                journal.EncodedBy = User.Identity.Name;

                db.LoanJourals.Add(journal);
                db.SaveChanges();

                return RedirectToAction("LoanJournal", new { documentNo = model.DocumentNo });
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult DeleteLoanJournalRemarks(int? id, string documentNo)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();

                var journal = db.LoanJourals.Where(w => w.ID == id).SingleOrDefault<LoanJournal>();
                db.LoanJourals.Remove(journal);
                db.SaveChanges();

                return RedirectToAction("LoanJournal", new { documentNo = documentNo });
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult PaymentHistory(string documentNo)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();
                var model = FundingHelper.GetLoanPaymentHistoryModel(db, documentNo);
                return View(model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult PaymentAddEdit(int? id, string documentNo)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();
                var model = FundingHelper.GetLoanPaymentAddEditModel(db, id, documentNo);

                return View(model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        [HttpPost]
        public ActionResult PaymentSave(LoanPaymentAddEditModel model, string command)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.Loans);

                var db = new DatabaseContext();

                if (command == AdministrationHelper.DBCommand.Add.ToString())
                {
                    db.LoanPayments.Add(model.LoanPayment);
                    db.SaveChanges();
                }
                else if (command == AdministrationHelper.DBCommand.Edit.ToString())
                {
                    db.Entry(model.LoanPayment).State = System.Data.EntityState.Modified;
                    db.SaveChanges();
                }
                else
                {
                    // cancelled
                }

                return RedirectToAction("LoanDetails", new { documentNo = model.LoanPayment.DocumentNo });
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }
    }
}
